#include <iostream>
#include <string>
using namespace std;

// 1. 抽象产品类 - 奶茶接口
class MilkTea {
public:
    virtual ~MilkTea() {}
    virtual string drink() const = 0;
    virtual string getName() const = 0;
};

// 2. 具体产品类 - 各种奶茶
class PearlMilkTea : public MilkTea {
public:
    string drink() const override {
        return "咕噜咕噜... 喝到了Q弹的珍珠！";
    }
    
    string getName() const override {
        return "珍珠奶茶";
    }
};

class TaroMilkTea : public MilkTea {
public:
    string drink() const override {
        return "香浓顺滑... 芋头香味充满口腔！";
    }
    
    string getName() const override {
        return "芋头奶茶";
    }
};

class ChocolateMilkTea : public MilkTea {
public:
    string drink() const override {
        return "丝滑浓郁... 巧克力在舌尖融化！";
    }
    
    string getName() const override {
        return "巧克力奶茶";
    }
};

// 3. 抽象创建者类 - 奶茶店总部
class MilkTeaShop {
public:
    virtual ~MilkTeaShop() {}
    
    // 工厂方法 - 每个分店自己决定怎么做奶茶
    virtual MilkTea* createMilkTea() const = 0;
    
    // 业务逻辑 - 总部的标准服务流程
    string serveTea() const {
        // 调用工厂方法创建奶茶
        MilkTea* tea = this->createMilkTea();
        
        // 使用奶茶
        string result = "欢迎光临！您的" + tea->getName() + "来了！\n";
        result += "体验：" + tea->drink();
        
        delete tea;  // 喝完清理
        return result;
    }
};

// 4. 具体创建者类 - 各家特色奶茶店
class PearlMilkTeaShop : public MilkTeaShop {
public:
    MilkTea* createMilkTea() const override {
        cout << "珍珠奶茶专卖店：现煮珍珠，调配奶茶..." << endl;
        return new PearlMilkTea();
    }
};

class TaroMilkTeaShop : public MilkTeaShop {
public:
    MilkTea* createMilkTea() const override {
        cout << "芋头奶茶专卖店：蒸煮芋头，手工捣泥..." << endl;
        return new TaroMilkTea();
    }
};

class ChocolateMilkTeaShop : public MilkTeaShop {
public:
    MilkTea* createMilkTea() const override {
        cout << "巧克力奶茶专卖店：融化巧克力，精心调配..." << endl;
        return new ChocolateMilkTea();
    }
};

// 5. 客户端代码 - 顾客
void customerOrder(const MilkTeaShop& shop) {
    cout << "顾客：我想买杯奶茶，不管什么店都能服务我" << endl;
    cout << shop.serveTea() << endl;
    cout << "----------------------------------------" << endl;
}

// 6. 使用示例
int main() {
    cout << "===== 工厂方法模式 - 奶茶店例子 =====" << endl;
    
    // 顾客去不同的奶茶店
    cout << "\n1. 去珍珠奶茶专卖店：" << endl;
    MilkTeaShop* pearlShop = new PearlMilkTeaShop();
    customerOrder(*pearlShop);
    
    cout << "2. 去芋头奶茶专卖店：" << endl;
    TaroMilkTeaShop taroShop;
    customerOrder(taroShop);
    
    cout << "3. 去巧克力奶茶专卖店：" << endl;
    ChocolateMilkTeaShop chocolateShop;
    customerOrder(chocolateShop);
    
    // 动态创建店铺的例子
    cout << "4. 根据用户选择动态创建店铺：" << endl;
    MilkTeaShop* shop = nullptr;
    
    int choice = 2;  // 模拟用户选择（1:珍珠, 2:芋头, 3:巧克力）
    
    switch(choice) {
        case 1:
            shop = new PearlMilkTeaShop();
            break;
        case 2:
            shop = new TaroMilkTeaShop();
            break;
        case 3:
            shop = new ChocolateMilkTeaShop();
            break;
    }
    
    if(shop) {
        cout << "根据您的选择，为您推荐店铺：" << endl;
        customerOrder(*shop);
        delete shop;
    }
    
    return 0;
}